package com.imashimaro.serializer;

import com.imashimaro.annotation.BigDecimalFormat;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.fasterxml.jackson.databind.ser.std.NumberSerializer;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import org.springframework.boot.jackson.JsonComponent;

import java.io.IOException;
import java.math.BigDecimal;

@JsonComponent
public class BigDecimalSerializer extends StdSerializer<BigDecimal> implements ContextualSerializer {
    /**
     * 保留小数位数
     */
    private int scale;

    /**
     * 取整策略
     *
     */
    private int model;

    /**
     * 是否转为字符串
     */
    private boolean isToString;


    public BigDecimalSerializer() {
        super(BigDecimal.class);
    }

    public BigDecimalSerializer(int scale, int model,boolean isToString) {
        this();
        this.model = model;
        this.scale = scale;
        this.isToString = isToString;
    }

    @Override
    public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException {
        BigDecimalFormat annotation = null;
        if (property != null){
            annotation = property.getAnnotation(BigDecimalFormat.class);
        }
        if (annotation != null){
            int scale = annotation.scale();
            int model = annotation.model();
            boolean toString = annotation.isToString();
            return new BigDecimalSerializer(scale,model,toString);
        }else {
            return new NumberSerializer(BigDecimal.class);
        }
    }

    @Override
    public void serialize(BigDecimal value, JsonGenerator gen, SerializerProvider provider) throws IOException {
        value = value.setScale(scale,model);
        gen.writeObject(isToString ? value.toString() : value );
    }
}
